﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CygwinPackageManager.Common;
using CygwinPackageManager.Properties;

namespace CygwinPackageManager
{
	[Docking(DockingBehavior.Ask)]
	[DefaultEvent("PredicateChanged")]
	public partial class PackagePredicate : UserControl
	{
		#region Control LifeCycle
		public PackagePredicate()
		{
			InitializeComponent();
		}
		#endregion

		#region Events
		public event EventHandler PredicateChanged;
		protected virtual void OnPredicateChanged(EventArgs e)
		{
			if (PredicateChanged != null)
				PredicateChanged(this, e);
		}
		#endregion

		#region Public Properties
		private IEnumerable<PackageCategory> _categories;
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public IEnumerable<PackageCategory> Categories
		{
			get { return _categories; }
			set
			{
				SetCategories(value);
				_categories = value;
			}
		}

		private IEnumerable<PackageStatus> _statuses;
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public IEnumerable<PackageStatus> Statuses
		{
			get { return _statuses; }
			set
			{
				SetStatuses(value);
				_statuses = value;
			}
		}

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public IEnumerable<int> SelectedCategoryIDs
		{
			get
			{
				return from category in lbCategories.SelectedItems.Cast<PackageCategory>()
					   select category.PackageCategoryID;
			}
			set
			{
				for (int i = 0; i < lbCategories.Items.Count; i++)
				{
					PackageCategory category = lbCategories.Items[i] as PackageCategory;
					lbCategories.SetSelected(i, value.Contains(category.PackageCategoryID));
				}
			}
		}

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public IEnumerable<int> SelectedStatusIDs
		{
			get
			{
				return from status in lbStatuses.SelectedItems.Cast<PackageStatus>()
					   select status.PackageStatusID;
			}
			set
			{
				for (int i = 0; i < lbStatuses.Items.Count; i++)
				{
					PackageStatus status = lbStatuses.Items[i] as PackageStatus;
					lbStatuses.SetSelected(i, value.Contains(status.PackageStatusID));
				}
			}
		}

		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public string FreeText
		{
			get { return tbFreeText.Text; }
			set { tbFreeText.Text = value; }
		}
		#endregion

		#region Private Methods
		private void SetCategories(IEnumerable<PackageCategory> value)
		{
			lbCategories.DataSource = (from category in value
									   orderby category.Name
									   select category).ToList();
		}

		private void SetStatuses(IEnumerable<PackageStatus> value)
		{
			lbStatuses.DataSource = (from status in value
									 orderby status.Name
									 select status).ToList();
		}
		#endregion

		#region Event Handlers
		private void lbCategories_SelectedIndexChanged(object sender, EventArgs e)
		{
			// TODO: Would be nice to have a SelectionChanged event like in the DataGridView.
			OnPredicateChanged(EventArgs.Empty);
		}
		private void lbStatuses_SelectedIndexChanged(object sender, EventArgs e)
		{
			// TODO: Would be nice to have a SelectionChanged event like in the DataGridView.
			OnPredicateChanged(EventArgs.Empty);
		}

		private void tbFreeText_TextChanged(object sender, EventArgs e)
		{
			OnPredicateChanged(EventArgs.Empty);
		}
		#endregion
	}
}
